package cn.tedu.kcircle.passport.adapter.rpc;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.tedu.kcircle.common.exception.BusinessException;
import cn.tedu.kcircle.common.exception.BusinessException;
import cn.tedu.kcircle.common.po.CurrentPrincipal;
import cn.tedu.kcircle.common.restful.ResponseCode;
import cn.tedu.kcircle.common.util.JwtUtil;
import cn.tedu.kcircle.passport.adapter.converter.PassportAdapterConverter;
import cn.tedu.kcircle.passport.api.rpc.PassportRpcApi;
import cn.tedu.kcircle.passport.protocol.dto.UserInfoDTO;
import cn.tedu.kcircle.passport.protocol.dto.UserLoginDTO;
import cn.tedu.kcircle.passport.repository.cache.UserStateCacheRepository;
import cn.tedu.kcircle.passport.service.bo.UserStateBO;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.security.SignatureException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
@AllArgsConstructor
@Slf4j
public class PassportRpcApiImpl implements PassportRpcApi {

    private UserStateCacheRepository userStateCacheRepository;
    private PassportAdapterConverter converter;
    @Override
    public UserInfoDTO checkLogin(UserLoginDTO userLoginDTO) {
        String jwt=userLoginDTO.getJwt();
        String usdAddr=userLoginDTO.getUserAddr();
        String userAgent=userLoginDTO.getUserAgent();
        if (jwt == null) {
            String message="jwt为空";
            log.error(message);
            throw new BusinessException(ResponseCode.BAD_REQUEST,message);
        }
        Claims parse = null;
        try {
            parse = JwtUtil.parse(jwt, JWT_SECRET_KEY);
        } catch (ExpiredJwtException e) {
            log.error("解析JWT时出现异常：ExpiredJwtException", e);
            String message = "操作失败，您的登录信息已经过期，请重新登录！";
            throw new BusinessException(ResponseCode.BAD_REQUEST,message);
        } catch (SignatureException ex) {
            log.error("解析JWT时出现异常：SignatureException");
            String message = "非法访问，你的本次操作已经被记录！";
            throw new BusinessException(ResponseCode.BAD_REQUEST,message);
        } catch (MalformedJwtException e) {
            log.error("解析JWT时出现异常：MalformedJwtException");
            String message = "非法访问，你的本次操作已经被记录！";
            throw new BusinessException(ResponseCode.BAD_REQUEST,message);
        } catch (Throwable e) {
            log.error("未知错误", e);
            String message = "服务器忙，请稍后再试!";
            throw new BusinessException(ResponseCode.INTERNAL_SERVER_ERROR, message);
        }

        CurrentPrincipal principal = BeanUtil.mapToBean(parse, CurrentPrincipal.class, true, new CopyOptions());
        Long id = principal.getUserId();
        UserStateBO userState = userStateCacheRepository.getUserState(id);
        if (userState == null) {
            String message="未认证";
            log.error(message);
            throw new BusinessException(ResponseCode.ERROR_UNAUTHORIZED,message);
        }
        if (!usdAddr.equals(principal.getUserAddr()) || !userAgent.equals(principal.getUserAgent())) {
            String message = "存在盗用风险";
            log.error(message);
            throw new BusinessException(ResponseCode.ERROR_CONFLICT,message);
        }
        if (userState.getEnable() == 0) {
            String message = "账号已禁用，请联系管理员";
            log.error(message);
            userStateCacheRepository.deleteUserState(id);
            throw new BusinessException(ResponseCode.ERROR_FORBIDDEN,message);
        }
        userStateCacheRepository.renewal(id);

        UserInfoDTO userInfoDTO = new UserInfoDTO();
        userInfoDTO.setUserId(id);
        userInfoDTO.setAuthorityJsonString(userState.getAuthorityJsonString());
        return userInfoDTO;
    }

    @Override
    public UserInfoDTO getLoginInfo(Long userId) {
        if(userId==null){
            return null;
        }
        UserStateBO userStateBO = userStateCacheRepository.getUserState(userId);
        if(userStateBO==null){
            return null;
        }
        if(userStateBO.getEnable()!=1){
            return null;
        }
        userStateCacheRepository.renewal(userId);
        return converter.bo2DTO(userStateBO);
    }


}
